<?php
/**
 * 数据字典服务类。
 	`id` bigint(20) unsigned not null auto_increment comment '主键', 
	`pid` bigint(20) unsigned  NOT NULL comment 'parent id',  
	`id_path` VARCHAR(100)  NOT NULL comment 'id path',    
	`code` VARCHAR(40)  NOT NULL,    
	`desc` VARCHAR(80)  NOT NULL,   
	`order` int(11) DEFAULT NULL, 
 * 
 */
class DictService extends Service {
	public $ROOT_NODE_ID = 0;
	public $ROOT_NODE_PARENTID = -1;
	
	public function createDict($ary_dict) {
		$ary_dict = $this->maintainIdPath($ary_dict);
		$result = M('Dict')->add($ary_dict);
		return $result;
	}
	
	public function updateDict($ary_dict) {
		$ary_dict = $this->maintainIdPath($ary_dict);
		$result = M('Dict')->save($ary_dict);
		return $result;
	}

	public function deleteDict($map) {
		$result = 0;
		foreach($map as $vo){
				$tempdict = M('Dict')->where(' id='.$vo)->find();
				$tmp = M('Dict')->where('id='.$vo)->delete();
				$sql = " id_path like '%.".$vo.".%' ";
				$tmp = M('Dict')->where($sql)->delete();
				$result = $result+$tmp;
		}
		return $result;
	}

	public function selectByParentId($parentId){
		$listdict = M('Dict')->where('pid='.$parentId)->order('`order` desc')->findAll();
		return $listdict;
	} 
	
	public function findByCode($code){
		$dict = M('Dict')->where(" code='".$code."'")->find();
		return $dict;
	}
	
	public function findByPrimaryKey($id) {
		$dict = M('Dict')->where(" id=".$id)->find();
		return $dict;
	}

	
	/*
	*	通过code查询所有父类．
	*	返回完整的继承关系到自身的数组．
	*/
	public function findAllParents($code){
		$dictself = M('Dict')->where(" code='".$code."'")->find();
		if(empty($dictself))return null;
		
		$pids	= explode('.', $dictself['id_path']);
		$map['id'] = array('in',$pids);
		$pdicts = M('Dict')->where($map)->findAll();
		
		$result;		$index = 0;
		foreach($pids as $pid){
				foreach($pdicts as $pdict){
						if($pid==$pdict['id']){
								$result[$index] = $pdict;
								$index++;
						}
				}
		}
		$result[$index] = $dictself;
		return $result;
	}
	
	
	/**
	 * 维护字典信息中的idPath属性，这个属性是内部使用的，因此不需要展示到客户端。
	 * 
	 * @param dept
	 */
	private function maintainIdPath($ary_dict) {
		// 如果是第一级节点
		if ($ary_dict['pid'] == $this->ROOT_NODE_ID) {
				$ary_dict['id_path']=".".$this->ROOT_NODE_ID.".";
		} else {
				// 如果不是第一级，则把上级部门的idPath值 + 部门编号 + "."
				$parentDict = $this->findByPrimaryKey($ary_dict['pid']);
				$ary_dict['id_path']=$parentDict['id_path'].$ary_dict['pid'].".";
		}
		return $ary_dict;
	}

	/**
	 * 判断一个字典类别是否已经具备了删除的条件。 一个字典类别如果要被删除需要具备下面的条件： 该字典类别不能有下级字典条目；
	 * 因此要删除一个部门必须先删除子字典条目。
	 * 
	 * @param id
	 *            指定部门的编号。
	 * @return 返回true表示该部门可以删除，false则不允许删除。
	 */
	private function isDeleteReady($id) {
		// 从设计上看，只有部门结构树中最顶上的逻辑节点的id才是等于0
		if (id <= $this->ROOT_NODE_ID) {
			return false;
		}

		// 1.检查该部门是否包含了下级字典，
		$subDictList = $this->loadDirectSubDicts($id);
		if (!empty($subDictList) && count($subDictList) > 0) {
			return false;
		}
		return true;
	}

	public function loadDirectSubDicts($id){
			$listdict = M('Dict')->where(" pid=".$id)->findAll();
			return $listdict;
	}
	
	/**
	 * 获得其下的所有数据数组
	 * @param unknown_type $code
	 * @param unknown_type $order
	 */
	public function getAllDictByCode($code,$order=' `id_path` ,`order` '){
			$dict = $this->findByCode($code);
			if(empty($dict)){
					return null;
			}
			$list = M('Dict')->where(" `id_path` like '%.".$dict['id'].".%' ")->order($order)->findAll();
			return $list;
	}
	
	
	/**
	 * 获得其下的所有数据的key value数组。array(code=>desc);
	 * Enter description here ...
	 * @param unknown_type $code
	 * @param unknown_type $order
	 */
	public function getAllDictKeyValueByCode($code,$order=' `id_path` ,`order` '){
			$dict = $this->findByCode($code);
			if(empty($dict)){
					return null;
			}
			$list = M('Dict')->where(" `id_path` like '%.".$dict['id'].".%' ")->order($order)->findAll();
			
			foreach($list as $vo){
				$result[$vo['code']]=$vo['desc'];
			}
			
			return $result;
	}
	
	
	/**
	 * 通过code获取，对应的直接子类。
	 * @param String $code			数据的code值
	 * @param String $ret_type		返回数据类型:	all-返回array('code'=>'desc',....)格式;
	 * 												code-返回array('code1','code2',....)格式;
	 */
	public function getAllDirectSubDicts($code,$ret_type='all'){
			$dict = $this->findByCode($code);

			if(empty($dict)){
				return null;
			}
			$order=' `id_path` ,`order` ';
			$listdict = M('Dict')->where(" pid=".$dict['id'])->order($order)->findAll();

			$result=$listdict;
			if($ret_type=='all'){
				unset($result);
				foreach($listdict as $vo){
					$result[$vo['code']]=$vo['desc'];
				}
			}
			if($ret_type=='code'){
				unset($result);
				foreach($listdict as $vo){
					$result[]=$vo['code'];
				}
			}
			return $result;
	}
	
	//服务初始化
	public function init($data = '') {
	}
	
	//运行服务，系统服务自动运行
	public function run() {
	}
}
?>